home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / clipper / nannws22.zip / LCPACK.C < prev    next >
Text File  |  1987-12-08  |  11KB  |  412 lines

  1. /***************************************************************/
  2. /* lcpack.c memo file packing program                          */
  3. /* for Lattice C 3.1 and Clipper                               */
  4. /* Author: Don L. Powells                                      */
  5. /* Purpose: Function to pack .dbt files                        */
  6. /* Usage: In Clipper program the function can be invoked as a  */
  7. /*        User-defined Function.                               */
  8. /*        Example: errcode=mpack(dbf_name)                     */
  9. /***************************************************************/
  10.  
  11. /* Include the necessary header files */ 
  12. #include "stdio.h" 
  13. #include "string.h" 
  14. #include "fcntl.h" 
  15. #include "extend.h" 
  16.  
  17. /* Define program constants */ 
  18. #define DBT_EXT ".dbt" 
  19. #define DBF_EXT ".dbf" 
  20. #define SIZE 512 
  21. #define MODE 0 
  22. #define MAXFIELDS 1024 
  23. #define ONE_A '\032' 
  24. #define SPACE " " 
  25.  
  26. /* Declare variables and functions*/ 
  27. int  fieldlen[MAXFIELDS]; 
  28. int  memofields[MAXFIELDS]; 
  29. int  offset[MAXFIELDS]; 
  30. int packmem(); 
  31. void reterr(); 
  32.  
  33. /************* Function mpack **********/ 
  34. /* Purpose: Receives the parameter and checks to see if it */
  35. /*          has an extension */ 
  36.  
  37. void mpack() 
  38.    char *parm; 
  39.    int error; 
  40.    int i; 
  41.  
  42.    /* CHECK to be sure that a file name was passed */ 
  43.    if (PCOUNT != 1 || !ISCHAR(1)) 
  44.       _retni(1); 
  45.  
  46.    /* Use Clipper Extend system to get filename off stack */ 
  47.    parm = _parc(1); 
  48.  
  49.    /* Truncate the extension off the filename if passed */ 
  50.    i=0; 
  51.    while(parm[i] != 0L) 
  52.       { 
  53.       if(parm[i] == '.') 
  54.           parm[i] = 0L; 
  55.        ++i; 
  56.        } 
  57.  
  58.    /* Call the memo packing function and return the error code */
  59.    /* to Clipper */ 
  60.    error = packmem(parm); 
  61.    _retni(error); 
  62.  
  63. /************* Function packmem **********/ 
  64. /* Purpose: To pack dbt files by writing only the current, */ 
  65. /*          usable memos to another file, updating the dbf */
  66. /*          pointers and deleting the old dbt file.        */
  67.  
  68. packmem(filename) 
  69. char *filename; 
  70. char dbf_name[64]; 
  71. char dbt_name[64]; 
  72. int  old_dbt; 
  73. int  dbf; 
  74. int  new_dbt; 
  75. unsigned char buffer[513]; 
  76. int count; 
  77. long apos; 
  78. long rpos; 
  79. long reccnt; 
  80. unsigned int hdrsize; 
  81. unsigned int recsize; 
  82. int  numofflds; 
  83. int  numofmems; 
  84. int  numflds2add; 
  85. unsigned int nextblk; 
  86. int  i; 
  87. int  j; 
  88. int  k; 
  89. int  m; 
  90. char blk_num[11]; 
  91. int  curr_blk; 
  92. int  onea_found; 
  93. char lead_spc[10]; 
  94.  
  95. typedef struct 
  96.    char sign; 
  97.    char date[3]; 
  98.    long recc; 
  99.    unsigned int data_off; 
  100.    unsigned int rec_size; 
  101.    char pad[20]; 
  102. } DBF_HEADER; 
  103.  
  104. DBF_HEADER head; 
  105.  
  106. struct 
  107.    { 
  108.    char  fieldname[11]; 
  109.    char  field_type; 
  110.    char  fpad[4]; 
  111.    char  field_len; 
  112.    char  field_dec; 
  113.    char  res_bytes[14]; 
  114.    }field_def; 
  115.  
  116. /* Concatenate extensions to passed name */ 
  117. strcpy(dbf_name,filename); 
  118. strcpy(dbt_name,filename); 
  119. strcat(dbf_name,DBF_EXT); 
  120. strcat(dbt_name,DBT_EXT); 
  121.  
  122. printf("DP & Associates "); 
  123. for (i=1;i < 25;i++) 
  124.    printf("\n"); 
  125. printf("            Packing %s. Please wait a moment.",dbt_name);
  126. for (i=1;i < 12;i++) 
  127.    printf("\n"); 
  128.  
  129. /* OPEN the dbf file */ 
  130. if ((dbf = open(dbf_name,O_RDWR | O_RAW)) == -1) 
  131.    { 
  132.    return(2); 
  133.    } 
  134.  
  135. /* READ first byte of the dbf file and if it is !=83H then */
  136. /*      give an error message saying this is not a dbf */
  137. /*      file with a memo field */ 
  138. if ((count = read(dbf,buffer,1)) < 1) 
  139.    { 
  140.    /* CLOSE the dbf file */ 
  141.    close(dbf); 
  142.    return(3); 
  143.    } 
  144. else 
  145.    if (buffer[0] != 0x83) 
  146.    { 
  147.    /* CLOSE the dbf file */ 
  148.    close(dbf); 
  149.    return(4); 
  150.    } 
  151.  
  152. /* RENAME original dbt file as temp (cpackmem.bak) */ 
  153. if (rename(dbt_name,"cpackmem.bak") == -1) 
  154.    { 
  155.    /* CLOSE the dbf file */ 
  156.    close(dbf); 
  157.    return(5); 
  158.    } 
  159.  
  160. /* OPEN the temp dbt file */ 
  161. if ((old_dbt = open("cpackmem.bak",O_RDONLY | O_RAW)) == -1) 
  162.    { 
  163.    /* CLOSE the dbf file */ 
  164.    close(dbf); 
  165.    rename("cpackmem.bak",dbt_name); 
  166.    return(6); 
  167.    } 
  168.  
  169. /* CREATe the new dbt file with original name */ 
  170. if ((new_dbt = open(dbt_name,O_RDWR | O_TRUNC | O_RAW | O_CREAT, 
  171.    S_IREAD | S_IWRITE)) == -1) 
  172.    { 
  173.    /* CLOSE the dbf file */ 
  174.    close(dbf); 
  175.    rename("cpackmem.bak",dbt_name); 
  176.    return(7); 
  177.    } 
  178.  
  179. /* READ the first 512 byte block from cpackmem.bak and WRITE */
  180. /* to new dbt */ 
  181. if ((count = read(old_dbt,buffer,SIZE)) < SIZE) 
  182.    { 
  183.    reterr(dbt_name); 
  184.    return(8); 
  185.    } 
  186.  
  187. if ((count = write(new_dbt,buffer,SIZE)) < SIZE) 
  188.    { 
  189.    reterr(dbt_name); 
  190.    return(9); 
  191.    } 
  192.  
  193. /***************************************************************/ 
  194. /* READ the dbf header to find out how many memo fields there  */
  195. /*      are and what their offsets are. */ 
  196.  
  197. if ((apos = lseek(dbf,0L,MODE)) == -1) 
  198.    { 
  199.    reterr(dbt_name); 
  200.    return(10); 
  201.    } 
  202.  
  203. if ((count = read(dbf,(char *) &head,sizeof(head))) < 32) 
  204.    { 
  205.    reterr(dbt_name); 
  206.    return(11); 
  207.    } 
  208.  
  209. /* LSEEK and READ bytes 4-7 to get number of records and store */
  210. /*      in a memory variable reccnt */ 
  211.  
  212. reccnt = head.recc; 
  213.  
  214. /* LSEEK and READ bytes 8-9 to get the number of bytes in the  */
  215. /*    header and store in a memory variable hdrsize */ 
  216.  
  217. hdrsize = head.data_off; 
  218.  
  219. /* LSEEK and READ bytes 10-11 to get the number of bytes in */
  220. /*    the record and store in a memory variable recsize */ 
  221.  
  222. recsize = head.rec_size; 
  223.  
  224. /* LSEEK byte 32 the first field descriptor */ 
  225.  
  226. rpos = 32; 
  227. if ((apos = lseek(dbf,rpos,MODE)) == -1) 
  228.    { 
  229.    reterr(dbt_name); 
  230.    return(12); 
  231.    } 
  232.  
  233. numofflds = 0; 
  234. numofmems = 0; 
  235.  
  236. /*    READ the 32 byte field descriptor into the buffer */ 
  237. if ((count = read(dbf,(char *) &field_def,sizeof(field_def)))<32) 
  238.    { 
  239.    reterr(dbt_name); 
  240.    return(13); 
  241.    } 
  242.  
  243. /* WHILE buffer[1] != 0DH */ 
  244. while(field_def.fieldname[0] != 0x0D) 
  245.    { 
  246.    /*    numofflds = numofflds + 1 */ 
  247.    numofflds ++; 
  248.  
  249.    /*    IF buffer[11] (fieldtype) is M */ 
  250.    /*       INCrement numofmems */ 
  251.    /*       add field num to */
  252.    /*         memofield array {memofield[numofmems]=numofflds} */
  253.    /*    ENDIF (fieldtype=M) */ 
  254.  
  255.    if (field_def.field_type == 'M') 
  256.       { 
  257.       numofmems++; 
  258.       memofields[numofmems] = numofflds; 
  259.       } 
  260.  
  261.    /*    LSEEK byte 16 to get field length and add to */
  262.    /*       fieldlen array */
  263.    /*    fieldlen[numofflds] = buffer[16] */ 
  264.    fieldlen[numofflds] = field_def.field_len; 
  265.  
  266.    /*    READ the 32 byte field descriptor into the buffer */ 
  267.    if ((count = read(dbf,(char *) &field_def,sizeof(field_def))) 
  268.       <32) 
  269.    { 
  270.    reterr(dbt_name); 
  271.    return(14); 
  272.    } 
  273.    } 
  274.  
  275. /********* Build offset array **********************************/ 
  276. /* FOR i=1 to numofmems */ 
  277. for (i=1;i<=numofmems;i++) 
  278.    /*    numflds2add = memofields[i] - 1 */ 
  279.    numflds2add = memofields[i] - 1; 
  280.  
  281.    offset[i] = 1; 
  282.    /*    FOR j=1 to numflds2add */ 
  283.    for (j=1;j<=numflds2add;j++) 
  284.    { 
  285.       /*       offset[i] = offset[i] + fieldlen[j] */ 
  286.       offset[i] = offset[i] + fieldlen[j]; 
  287.    /*    NEXT (fieldlen to add) */ 
  288.    } 
  289. /* NEXT (memo field) */ 
  290. /* ******* Process memo data ***********************************/ 
  291. nextblk = 1; 
  292. /* FOR i=1 to reccnt */ 
  293. for (i=1;i<=reccnt;i++) 
  294.    /* FOR j=1 to number of memo fields (numofmems) in dbf file */
  295.    for (j=1;j<=numofmems;j++) 
  296.    { 
  297.    /*       find pointer (512 byte block#) to memo field */ 
  298.    /*       LSEEK (hdrsize + (i-1) * recsize + offset[j]) and */
  299.    /*       READ 10 bytes*/ 
  300.    rpos = hdrsize + (i-1) * recsize + offset[j]; 
  301.    apos = lseek(dbf,rpos,MODE); 
  302.  
  303.    blk_num[10] = '\0'; 
  304.  
  305.    count = read(dbf,blk_num,10); 
  306.  
  307.    curr_blk = atoi(blk_num); 
  308.  
  309.    if (curr_blk != 0) 
  310.      { 
  311.          /* LSEEK -10 bytes and WRITE new pointer # in dbf file*/
  312.          rpos = -10; 
  313.          apos = lseek(dbf,rpos,1); 
  314.  
  315.          sprintf(blk_num,"%d",nextblk); 
  316.          if ((count = strlen(blk_num)) < 10) 
  317.             { 
  318.             strcpy(lead_spc